home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / printing / magicfil.2 / magicfilter-1.2.tar / magicfilter-1.2 / loadconfig.c < prev    next >
C/C++ Source or Header  |  1995-03-30  |  4KB  |  198 lines

  1. /*
  2.  *  loadconfig.c
  3.  *
  4.  *  Copyright ⌐ 1995 H. Peter Anvin
  5.  *
  6.  *  Load the configuration file
  7.  */
  8.  
  9. #include "magicfilter.h"
  10.  
  11. #define MAX_LINE 4096        /* Size of line buffer */
  12.  
  13. #define die(M) do { fprintf(stderr, "%s:%d: %s\n", file, lineno, (M)); \
  14.             fclose(f); return NULL; } while(0);
  15.  
  16. /*
  17.  * char *getline(FILE *f, char *file, int *lineno)
  18.  *
  19.  * Get a logical line from file f; returning a pointer to the allocated
  20.  * storage.  Advance the line pointer by # of lines.  file used for
  21.  * error messages.
  22.  */
  23.  
  24. static char *getline(FILE *f, char *file, int *line)
  25. {
  26.   char *buf, *p;
  27.   int buflen, spc, ch, bslash;
  28.   int lineno = *line;
  29.  
  30.   buf = p = malloc(BUFSIZ);
  31.   if ( !buf ) die("Out of memory");
  32.   buflen = spc = BUFSIZ;
  33.  
  34.   bslash = 0;
  35.  
  36.   while(1)
  37.     {
  38.       if ( !spc )        /* Risk for overrun? */
  39.     {
  40.       spc = p-buf;
  41.       if ( !(buf = realloc(buf, buflen += BUFSIZ)) )
  42.         die("Out of memory");
  43.       p = buf+spc;
  44.       spc = BUFSIZ;
  45.     }
  46.       
  47.       ch = getc(f);
  48.  
  49.       if ( ch == EOF )
  50.     {
  51.       if ( p == buf )
  52.         {
  53.           free(buf);
  54.           return NULL;    /* EOF */
  55.         }
  56.       else
  57.         {
  58.           bslash = 0;
  59.           ch = '\n';    /* End of file -> end of line */
  60.         }
  61.     }
  62.  
  63.       if ( ch == '\n' )
  64.     {
  65.       lineno++;
  66.       
  67.       if ( bslash )
  68.         {
  69.           p--;        /* Delete backslash-newline combo */
  70.           spc++;
  71.           while ( isspace(ch = getc(f)) ); /* Ignore leading whitespace */
  72.           ungetc(ch, f);
  73.         }
  74.       else
  75.         {
  76.           *p = '\0';
  77.           *line = lineno;
  78.           return buf;
  79.         }
  80.     }
  81.       else
  82.     {
  83.       bslash = (ch == '\\');
  84.       *(p++) = ch;
  85.       spc--;
  86.     }
  87.     }
  88. }
  89.  
  90.  
  91. /*
  92.  * struct datatype *load_config(char *file)
  93.  *
  94.  * Load the configuration file, returning the pointer to the lead node.
  95.  * In case of error, return NULL.
  96.  *
  97.  * The variable pointed to by in_block_size is set to the size needed
  98.  * for the input buffer.
  99.  */
  100.  
  101. struct datatype *load_config(char *file, int *in_block_size)
  102. {
  103.   FILE *f;
  104.   struct datatype *head = NULL;      /* Head pointer to linked list */
  105.   struct datatype **next = &head; /* Chase pointer to store in order */
  106.   struct datatype *new;
  107.   char *line, *p;
  108.   int lineno = 0;
  109.   int max_line = 0;
  110.   int bytes_needed = 0;
  111.   int offset;
  112.   int i;
  113.  
  114.   f = fopen(file, "r");
  115.   if ( !f )
  116.     {
  117.       perror(file);
  118.       return NULL;
  119.     }
  120.  
  121.   while ( (line = getline(f, file, &lineno)) != NULL )
  122.     {
  123.       offset = getoffset(line, &p);
  124.       
  125.       if ( offset == MAG_ERR ) die("Syntax error");
  126.       
  127.       if ( offset != MAG_COMMENT )
  128.     {
  129.       new = (struct datatype *) malloc(sizeof(struct datatype));
  130.       if ( !new ) die("Out of memory");
  131.       
  132.       if ( offset == MAG_DEFAULT )
  133.         {
  134.           new->offset = new->length = 0;
  135.           new->magic = new->mask = "";
  136.         }
  137.       else
  138.         {
  139.           i = getmagic(p, NULL, NULL, NULL); /* Get length of magic */
  140.           if ( i < 0 ) die("Syntax error");
  141.           new->offset = offset;
  142.           new->length = i;
  143.           new->magic = malloc(i);
  144.           new->mask = malloc(i);
  145.           if ( !(new->magic && new->mask) ) die("Out of memory");
  146.           if ( offset+i > bytes_needed )
  147.         bytes_needed = offset+i;
  148. #if DEBUG > 3
  149.           fprintf(stderr,"magic bytes: %d\n", i);
  150. #endif
  151.           getmagic(p, &p, new->magic, new->mask);
  152.         }
  153.       
  154.       if ( (new->action = getaction(p, &p)) < 0 )
  155.         die("Invalid action");
  156.       
  157.       if ( (i = strlen(p)) > 0 )
  158.         {
  159.           if ( !(new->command = malloc(i+1)) )
  160.         die("Out of memory");
  161.           strcpy(new->command, p);
  162.         }
  163.       else
  164.         new->command = "";
  165.       
  166.       /* Complete the linked list */
  167.       new->next = NULL;
  168.       *next = new;
  169.       next = &(new->next);
  170.       
  171. #if DEBUG > 2
  172.       fprintf(stderr,"Added config entry: \n");
  173.       fprintf(stderr,"   offset =  %d\n", new->offset);
  174.       fprintf(stderr,"   length =  %d\n", new->length);
  175.       fprintf(stderr,"   action =  %d\n", new->action);
  176.       fprintf(stderr,"   command = %s\n", new->command);
  177.       fprintf(stderr,"   bytes =   ");
  178.       
  179.       for ( i = 0 ; i < new->length ; i++ )
  180.         {
  181.           if ( (new->mask)[i] )
  182.         fprintf(stderr,"%03o ", (unsigned char)(new->magic)[i]);
  183.           else
  184.         fprintf(stderr,"??? ");
  185.         }
  186.       fprintf(stderr,"\n");
  187. #endif
  188.     }
  189.       free(line);
  190.     }
  191.   
  192.   fclose(f);
  193.   
  194.   if ( in_block_size ) *in_block_size = bytes_needed;
  195.   
  196.   return head;
  197. }
  198.